// StockBar.cpp : Implementation of CStockBar

#include "stdafx.h"
#include "StockBar.h"
#include "IE/HTMLEvent.h"
#include "update/UpdateManager.h"

const WCHAR TITLE_CStockBar[] = L"";

DEFINE_LOGGER(CStockBar)

// CStockBar

CStockBar::CStockBar()
	: m_dwBandID(0)
	, m_dwViewMode(0)
	, m_bShow(FALSE)
	, m_bEnterHelpMode(FALSE)
	, m_dwCookie(0)
{
	LOG("StockBar has been created 0x%x", this);
}

CStockBar::~CStockBar()
{
	LOG("Destroying 0x%x", this);
}

BOOL CStockBar::RegisterAndCreateWindow()
{
	LOG("Creating new toolbar window...");

	CRect rect(0,0,0,0);
	m_wndParent.GetClientRect(&rect);
	m_ReflectWnd.Create(m_wndParent, rect, NULL, WS_CHILD);

	LOG("New toolbar window hwnd: 0x%x", (HWND)Toolbar);

	return Toolbar.IsWindow();
}

// IDeskBand
STDMETHODIMP CStockBar::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO* pdbi)
{
	m_dwBandID	 = dwBandID;
	m_dwViewMode = dwViewMode;

	if (!pdbi)
		return E_POINTER;

	int iSize = Toolbar.GetMaxWidth();

	if (pdbi->dwMask & DBIM_MINSIZE)
		pdbi->ptMinSize.x = iSize, pdbi->ptMinSize.y = 22;
	if (pdbi->dwMask & DBIM_MAXSIZE)
		pdbi->ptMaxSize.x = 0, pdbi->ptMaxSize.y = -1; // ignored, width
	if (pdbi->dwMask & DBIM_INTEGRAL)
		pdbi->ptIntegral.x = 0, pdbi->ptIntegral.y = 0; // ignored, not sizeable
	if (pdbi->dwMask & DBIM_ACTUAL)
		pdbi->ptActual.x = iSize, pdbi->ptActual.y = 22;
	if (pdbi->dwMask & DBIM_TITLE)
		wcscpy_s(pdbi->wszTitle, sizeof(pdbi->wszTitle)/sizeof(WCHAR), TITLE_CStockBar);
	if (pdbi->dwMask & DBIM_BKCOLOR)
		pdbi->dwMask &= ~DBIM_BKCOLOR; //Use the default background color by removing this flag.
	if (pdbi->dwMask & DBIM_MODEFLAGS)
		pdbi->dwModeFlags = DBIMF_NORMAL;

	return S_OK;
}

// IOleWindow
STDMETHODIMP CStockBar::GetWindow(HWND* phwnd)
{
	if (!phwnd)
		return E_POINTER;

	*phwnd = Toolbar.m_hWnd;

	return S_OK;
}

STDMETHODIMP CStockBar::ContextSensitiveHelp(BOOL fEnterMode)
{
	m_bEnterHelpMode = fEnterMode;

	return S_OK;
}

// IDockingWindow
STDMETHODIMP CStockBar::CloseDW(unsigned long dwReserved)
{
	ShowDW(FALSE);

	return S_OK;
}

STDMETHODIMP CStockBar::ResizeBorderDW(const RECT* prcBorder, IUnknown* punkToolbarSite, BOOL fReserved)
{
	// Not used by any band object.
	return E_NOTIMPL;
}

STDMETHODIMP CStockBar::ShowDW(BOOL fShow)
{
	m_bShow = fShow;
	Toolbar.ShowWindow(m_bShow ? SW_SHOW : SW_HIDE);

	return S_OK;
}

void CStockBar::UnsetSite()
{
	try
	{
		LOG("UnsetSite...");

		if (m_browser && m_dwCookie)
			AtlUnadvise(m_browser, DIID_DWebBrowserEvents2, m_dwCookie), m_dwCookie = 0;

		Toolbar.SetBrowser(NULL);
		m_browser.Release();
		m_spUnkSite.Release();
		m_pSite.Release();

		m_wndParent = NULL;
	}
	catch(...)
	{
		LOG("EXCEPTION on UnsetSite in 0x%x", this);
	}
}

// IObjectWithSite
STDMETHODIMP CStockBar::SetSite(IUnknown* pUnkSite)
{
	UnsetSite();

	LOG("SetSite 0x%x for bar 0x%x", (DWORD)pUnkSite, (DWORD)this);

	//If punkSite is not NULL, a new site is being set.
	if (!pUnkSite)
		return S_OK;	

	try
	{
		//Get the parent window.
		CComPtr<IOleWindow> oleWindow;
		if(SUCCEEDED(pUnkSite->QueryInterface(&oleWindow)) && oleWindow)
			oleWindow->GetWindow(&m_wndParent.m_hWnd);

		ATLTRACE( _T("CStockBar\t- SetSite: parent hwnd 0x%x\n"), m_wndParent );
		if(!m_wndParent || !m_wndParent.IsWindow())
			return E_FAIL;

		if(!RegisterAndCreateWindow())
			return E_FAIL;

		if(FAILED(__super::SetSite(pUnkSite)))
			return E_FAIL;

		//Get and keep the IInputObjectSite pointer.
		if(FAILED(pUnkSite->QueryInterface(IID_IInputObjectSite, (LPVOID*)&m_pSite)))
			return E_FAIL;

		CComPtr<IOleCommandTarget> cmdTarget;
		if (FAILED(pUnkSite->QueryInterface(&cmdTarget)) || !cmdTarget)
			return E_FAIL;

		CComPtr<IServiceProvider> provider;
		if (FAILED(cmdTarget->QueryInterface(&provider)) || !provider)
			return E_FAIL;

		if (FAILED(provider->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, (LPVOID*)&m_browser)) || !m_browser)
			return E_FAIL;

		ATLASSERT(m_browser);

		Toolbar.SetBrowser(m_browser);

		if (FAILED(AtlAdvise(m_browser, GetUnknown(), DIID_DWebBrowserEvents2, &m_dwCookie)))
			m_dwCookie = 0;

		LOG("SetSite 0x%x for bar 0x%x is done", (DWORD)pUnkSite, (DWORD)this);

		return S_OK;
	}
	catch(...)
	{
		LOG("EXCEPTION on SetSite in 0x%x", this);
	}

	return E_FAIL;
}

STDMETHODIMP CStockBar::DocumentComplete(IDispatch* pDisp, VARIANT* URL)
{
	if (!pDisp)
		return S_OK;

    CheckForUpdate();

    return S_OK;
}

void CStockBar::CheckForUpdate()
{
	CUpdateManager &rUpdateManager = CUpdateManager::Instance();
	if (!rUpdateManager.IsUpToDate())
	{
        if (IDYES == ::MessageBox(m_browser.hwnd, ::GetString(IDS_NEW_VERSION_IS_AVAILABLE), ::GetString(IDS_UPDATES_TITLE), MB_YESNO|MB_ICONQUESTION ) && !rUpdateManager.GetUpdateURL().IsEmpty())
			API::Shell::Execute( rUpdateManager.GetUpdateURL() );
	}
}
